﻿using System.Collections.Generic;
using UnityEngine;

namespace TinyWnd
{
    public enum WndId
    {
        none,
        mainMenu,
        topbar,
        shop,
        msgBox,
        rank,
        skill,
        level,
        levelDetail,
        matching,
        matchResult,
    }
}

namespace TinyWnd
{
    public static class WndResource
    {
        static string _directory = "UIPrefab/";
        static Dictionary<WndId, string> _prefabs = new Dictionary<WndId, string>
        {
            {WndId.mainMenu, "MainMenuWnd"},
            {WndId.topbar, "TopbarWnd"},
            {WndId.shop, "ShopWnd"},
            {WndId.msgBox, "MsgBoxWnd"},
            {WndId.rank, "RankWnd"},
            {WndId.skill, "SkillWnd"},
            {WndId.level, "LevelWnd"},
            {WndId.levelDetail, "LevelDetailWnd"},
            {WndId.matching, "MatchingWnd"},
            {WndId.matchResult, "MatchResultWnd"},
        };


        public static string GetPrefbPath(WndId id)
        {
            string path;
            if (_prefabs.TryGetValue(id, out path))
                return _directory + path;
            else
                return string.Empty;
        }
    }
}

namespace TinyWnd
{
    // 窗口优先级顺序是 normal < toolbar < popup 。
    // normal 类型用于功能开发，toolbar 是工具栏，popup 优先级最高提供提示功能如消息框。
    // 同类型的窗口互斥显示，不能同时显示，具体表现为显示新的窗口会隐藏之前显示的窗口，关闭窗口才会再显示上个被隐藏的窗口。
    // 具体使用时，toolbar 是一直显示，popup 是显示然后隐藏。normal 是用于功能开发，因此会出现窗口跳转。
    // 此外进入战斗时会隐藏当前显示的所有窗口，结束战斗时再恢复。
    public enum WndType
    {
        normal = 0,
        toolbar, // 工具栏窗口，例如关闭窗口按钮。比 normal 窗口优先级高。
        popup, 
    }

    public enum WndShowMode
    {
        nothing = 0,
        hideOther,
    }

    public enum WndColliderMode
    {
        none,
        transparent,
        opaque,
    }

    public abstract class WndContentData
    {

    }

    public class Utility
    {
        public static void AddChild(Transform parent, Transform child, bool changeLayer = true)
        {
            child.parent = parent;
            child.localEulerAngles = child.localPosition = Vector3.zero;
            child.localScale = Vector3.one;

            if (changeLayer)
                ChangeLayer(child, parent.gameObject.layer);
        }

        public static void ChangeLayer(Transform target, int layer)
        {
            target.gameObject.layer = layer;
            foreach (Transform child in target)
                ChangeLayer(child, layer);
        }

        public static Transform FindChild(Transform parent, string name, bool deepFind = false)
        {
            Transform tran = parent.Find(name);
            if (tran != null || !deepFind)
                return tran;
            foreach (Transform child in parent)
            {
                tran = FindChild(child, name, true);
                if (tran != null)
                    break;
            }
            return tran;
        }

        public static T FindChild<T>(Transform parent, string name, bool deepFind = false) where T : Component
        {
            Transform tran = FindChild(parent, name, deepFind);
            if (tran != null)
                return tran.GetComponent<T>();
            return null;
        }

        // 按照从小到大的顺序返回。
        public static List<UIPanel> GetSortedPanels(Transform tran, bool includeInactive)
        {
            UIPanel[] panels = tran.GetComponentsInChildren<UIPanel>(includeInactive);
            var lst = new List<UIPanel>(panels);
            lst.Sort(delegate(UIPanel p1, UIPanel p2)
            {
                return p1.depth - p2.depth;
            });
            return lst;
        }

        // 添加带有 collider 的全屏背景图。
        public static GameObject AddColliderBg(Transform target, string maskName, UIAtlas altas, bool isTransparent)
        {
            GameObject colBg = null;
            Transform tran = FindChild(target, "ColliderBg", true);
            if (tran == null)
            {
                List<UIPanel> lst = GetSortedPanels(target, true);
                if (lst == null)
                {
                    Log.Error<Utility>("no panels in this target:{0}", target.name);
                    return null;
                }

                // 背景色深度最小，因此添加到深度最小的 panel 下。
                Transform minTran = lst[0].transform;
                GameObject bgGo = new GameObject("WindowBg");
                AddChild(minTran, bgGo.transform);

                UIWidget widget = null;
                if (!isTransparent)
                    widget = NGUITools.AddSprite(bgGo, altas, maskName);
                else
                    widget = NGUITools.AddWidget<UIWidget>(bgGo);
                widget.depth = -5;
                widget.alpha = 0.4f;
                widget.name = "ColliderBg";
                colBg = widget.gameObject;

                // 设置全屏。
                UIStretch stretch = colBg.AddComponent<UIStretch>();
                stretch.style = UIStretch.Style.Both;
                stretch.relativeSize = new Vector2(1.5f, 1.5f);

                NGUITools.AddWidgetCollider(colBg);
            }
            return tran != null ? tran.gameObject : colBg;
        }
    }

    public static class Log
    {
        public static void Info<T>(string fmt, params object[] args)
        {
            var m = string.Format(fmt, args);
            var msg = string.Format("[{0}] {1}", typeof(T).Name, m);
            UnityEngine.Debug.Log(msg);
        }

        public static void Error<T>(string fmt, params object[] args)
        {
            var m = string.Format(fmt, args);
            var msg = string.Format("[{0}] {1}", typeof(T).Name, m);
            UnityEngine.Debug.LogError(msg);
        }
    }
}
